package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 员工控制类
 *
 */
@RestController
@RequestMapping("/employee")
@Slf4j
@Api(tags = "员工管理接口")
public class EmployeeController {
    // 注入service
    @Autowired
    private EmployeeService employeeService;

    // 写接口，对前端我们提供的就成为接口，接口联调
    // 写控制器方法，三要素：方法名，返回值，参数列表
    // 还有注解
    // 前后端是统一返回值
    // 如果我们的方法，需要servlet api对象，IOC容器自动注入给我们
    @PostMapping("/login")
    public R<Employee> login(
            HttpServletRequest request,
            @RequestBody Employee employee){
        // 接收+封装
        log.info("[登录]  用户名:{},密码:{}",employee.getUsername(),employee.getPassword());
        // 调用 暂时不写,假设登陆成功
        // 1.根据用户名去查询用户
        // 根据用户名查询用户getOne方法，参数是Wrapper(条件）
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        // 第1个参数数据库表字段
        // select * from employee where username  = 'admin'
        queryWrapper.eq(Employee::getUsername,employee.getUsername());
        Employee dbEmployee = employeeService.getOne(queryWrapper);
        if(dbEmployee == null){
            return R.error("登录失败，该员工不存在！！！");
        }
        // 2.比对密码
        String dbPassword =  dbEmployee.getPassword(); // md5加密的
        String formPassword = employee.getPassword(); // 未加密->md5之后，与数据比对
        String md5Password = DigestUtils.md5DigestAsHex(formPassword.getBytes());
        if(!dbPassword.equals(md5Password)){
            return R.error("登录失败，密码不正确！！！");
        }
        // 3.查看员工状态
        if(dbEmployee.getStatus() == 0){
            return R.error("员工已禁用");
        }

        // 4.把员工ID放入session (我们后面的功能需要）从请求对象获取session
        request.getSession().setAttribute("employee",dbEmployee.getId());
        // 响应前端
        return R.success(dbEmployee);
    }

    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request){
        // 退出的时候做什么？后端做什么呢？
        // 如果退出了，session的内容是否要清楚,直接session失效即可
        request.getSession().invalidate();
        return R.success("退出成功");

    }
    // 返回字符串,请求POST
    // 方法名，返回值，方法参数（接收JSON数据）
    @PostMapping
    public R<String> saveEmployee(
            HttpServletRequest request,
            @RequestBody  Employee employee){
        log.info("[新增员工:线程Id:{}  emp:{}]",Thread.currentThread().getId(),employee);
        // 设置初始密码("123456")，数据库的密码是Md5
        String dbPassword = DigestUtils.md5DigestAsHex("123456".getBytes());
        employee.setPassword(dbPassword);
        // 设置创建和更新的时间
//        LocalDateTime localDateTime = LocalDateTime.now(); // 获取一个系统当前时间
//        employee.setCreateTime(localDateTime);
//        employee.setUpdateTime(localDateTime);

        // 获取当前登录用户的Id,这条记录是当前用户添加或更新的
//        Object obj = request.getSession().getAttribute("employee");
//        Long loginUserId = (Long) request.getSession().getAttribute("employee");
//        employee.setCreateUser(loginUserId);
//        employee.setUpdateUser(loginUserId);

        // 调用service保存员工，MP在插入数据时，取看看employee实体类上是否设置了填充策略
        employeeService.save(employee);
        return R.success("新增成功");
    }

    // 增加一个控制器方法，对应前端的分页查询请求
    // /page?page=1&pageSize=10&name=zhangsan
    // 前端是Get请求，是通过查询串
    // 返回类型 类型是分页,是通过分页插件获取的分页对象
    //  返回类型  方法名(参数列表)
    // 分页返回数据时，ID的Long转字符串精度丢失 （JSON转换导致）
    // JSON对象，转JSON字符串的，我们需要单独设置
    // JavaLong值，到前端数字类型，精度丢失，这个时候，我们在JSON转换，提前把Long转字符串

    @GetMapping("/page")
    @ApiOperation(value = "员工分页列表查询") // 接口的说明
    @ApiImplicitParams({    // 方法参数的说明
            @ApiImplicitParam(name = "page",value = "当前页码",required = true),
            @ApiImplicitParam(name = "pageSize",value = "每页条数",required = true),
            @ApiImplicitParam(name = "name",value = "员工名字",required = false)
    })
    public  R<Page>    findByPage(Integer page,
                                  Integer pageSize,
                                  String name){
        log.info("page:{},pageSize:{},name:{}",page,pageSize,name);
        // 需要把当前页面和每页条数赋值给Page对象
        Page pageInfo = new Page(page,pageSize);
        // 接下来使用MP来完成分页查询，如果使用MP做分页查询，前提条件是，设置分页插件
        // wrapper是条件
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper();
        // 如果没有name,就没有条件
        wrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
        wrapper.orderByDesc(Employee::getUpdateTime);
        employeeService.page(pageInfo,wrapper);

        return R.success(pageInfo);
    }

    // 写一个控制器方法，对应put请求
    // 返回值 方法名(参数列表-put请求，json数据）
    @PutMapping
    public R<String> update(
            HttpServletRequest request,
            @RequestBody Employee employee){
        // 先调试，确保你的数据接收没有问题的
        log.info("[更新员工:{}]",employee);
        // 调用service完成用户信息的更新,更新数据，我们看看还有哪些需要设置的？
        // 每个有公共字段，更新时间和更新用户必须设置
//        employee.setUpdateTime(LocalDateTime.now());
//
//        Long loginUserId = (Long) request.getSession().getAttribute("employee");
//        employee.setUpdateUser(loginUserId);
        // 如果公共字段在这里面没有设置，告知MP去自动填充
        employeeService.updateById(employee);
        return R.success("员工信息修改成功");
    }

    // 写一个控制器方法，对应根据ID查询
    // 返回值 方法名(参数列表-id,是通过路径传参)
    // /employee/1604754255787327490
    @GetMapping("/{id}")
    public R<Employee> findById(@PathVariable Long id){
        log.info("[根据ID查询:{}]",id);
        // 调用service，根据ID获取对象
        Employee employee = employeeService.getById(id);
        if(employee != null){
            return R.success(employee);
        }
        return R.error("未找到该员工");
    }

}
